package com.seleniti.enpareja.android.ui.widget;

import org.ioc.commons.impl.android.common.util.OnValueChangeEventListener;
import org.ioc.commons.impl.android.ui.HasEnabledWrapper;
import org.ioc.commons.impl.android.ui.HasLoaderWrapper;
import org.ioc.commons.impl.android.ui.HasTextWrapper;
import org.ioc.commons.impl.android.ui.HasValueWrapper;
import org.ioc.commons.impl.android.ui.HasVisibilityWrapper;
import org.ioc.commons.impl.android.ui.LinearLayoutDisplay;
import org.ioc.commons.ui.HasEnabled;
import org.ioc.commons.ui.HasLoader;
import org.ioc.commons.ui.HasText;
import org.ioc.commons.ui.HasValue;
import org.ioc.commons.ui.HasVisibility;
import org.ioc.commons.ui.features.Info;
import org.ioc.commons.utils.array.ArrayUtils;

import android.content.Context;
import android.text.Html;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;

import com.dwivedi.androidformvalidation.validator.Field;
import com.dwivedi.androidformvalidation.validator.Form;
import com.dwivedi.androidformvalidation.validator.validations.IsEmail;
import com.dwivedi.androidformvalidation.validator.validations.MatchPattern;
import com.dwivedi.androidformvalidation.validator.validations.NotEmpty;
import com.seleniti.enpareja.android.R;
import com.seleniti.enpareja.controller.model.integration.database.domain.Gender;
import com.seleniti.enpareja.controller.model.integration.database.domain.User;
import com.seleniti.enpareja.controller.ui.widget.UserForm;
import com.seleniti.enpareja.controller.ui.widget.UserFormPresenter;

public class UserFormWidget extends
		LinearLayoutDisplay<UserForm.Event, UserForm.Operation, UserForm.Action, UserForm.Presenter> implements
		UserForm {

	private LayoutInflater inflater;
	private TextView caption;
	private EditText userEmail;
	private Spinner gender;
	private EditText password;
	private EditText password2;
	private Button btnSave;
	private boolean tryLoginOnSave;
	private EditText nickName;
	private ProgressBar savingLoader;
	private InfoInlineWidget extraInfo;
	private TextView lblTryingLogin;
	private LinearLayout couplePanel;
	private TextView coupleInfo;
	private Form form;
	private ProgressBar gettingLoader;
	private InfoInlineWidget userEmailCheckInfo;
	private InfoInlineWidget passwordCheckInfo;
	private LinearLayout passwordDiv;
	private Button btnDownloadApp;
	private boolean showDownloadAppWhenPassword;
	private Button btnBreakUp;
	private LinearLayout testPanel;
	private LinearLayout singlePanel;
	private Button btnDropSingleMode;
	private Button btnDropTestMode;
	private ProgressBar breakingUpLoader;
	private ProgressBar dropSingleModeLoader;
	private ProgressBar dropTestModeLoader;
	private TextView txtDropSingleMode;
	private TextView txtDropTestMode;

	public UserFormWidget(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		this.presenter = new UserFormPresenter(this, eventbus, operationManager, actionController);
		this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		inflater.inflate(R.layout.user_form, this, true);
		this.caption = (TextView) findViewById(R.id.caption);
		this.userEmail = (EditText) findViewById(R.id.email);
		this.nickName = (EditText) findViewById(R.id.nickName);
		this.gender = (Spinner) findViewById(R.id.gender);
		this.password = (EditText) findViewById(R.id.password);
		this.password2 = (EditText) findViewById(R.id.password2);
		this.btnSave = (Button) findViewById(R.id.btnSave);
		this.savingLoader = (ProgressBar) findViewById(R.id.savingLoader);
		this.extraInfo = (InfoInlineWidget) findViewById(R.id.extraInfo);
		this.lblTryingLogin = (TextView) findViewById(R.id.lblTryingLogin);
		this.couplePanel = (LinearLayout) findViewById(R.id.couplePanel);
		this.coupleInfo = (TextView) findViewById(R.id.coupleInfo);
		this.gettingLoader = (ProgressBar) findViewById(R.id.gettingLoader);
		this.userEmailCheckInfo = (InfoInlineWidget) findViewById(R.id.userEmailCheckInfo);
		this.passwordCheckInfo = (InfoInlineWidget) findViewById(R.id.passwordCheckInfo);
		this.passwordDiv = (LinearLayout) findViewById(R.id.passwordDiv);
		this.btnDownloadApp = (Button) findViewById(R.id.btnDownloadApp);
		this.btnBreakUp = (Button) findViewById(R.id.btnBreakUp);
		this.testPanel=(LinearLayout) findViewById(R.id.testPanel);
		this.singlePanel=(LinearLayout) findViewById(R.id.singlePanel);
		this.btnDropSingleMode=(Button) findViewById(R.id.btnDropSingleMode);
		this.btnDropTestMode=(Button) findViewById(R.id.btnDropTestMode);
		this.breakingUpLoader=(ProgressBar) findViewById(R.id.breakingUpLoader);
		this.dropSingleModeLoader=(ProgressBar) findViewById(R.id.dropSingleModeLoader);
		this.dropTestModeLoader=(ProgressBar) findViewById(R.id.dropTestModeLoader);
		
		this.txtDropSingleMode = (TextView) findViewById(R.id.txtDropSingleMode);
		this.txtDropSingleMode.setText(Html.fromHtml(context.getString(R.string.you_are_single)));
		
		this.txtDropTestMode = (TextView) findViewById(R.id.txtDropTestMode);
		this.txtDropTestMode.setText(Html.fromHtml(context.getString(R.string.you_are_in_test_mode)));
		
		this.form = new Form(context);
		this.form.addField(Field.using(userEmail).validate(IsEmail.build(context, R.string.email_required)));
		this.form.addField(Field.using(nickName).validate(NotEmpty.build(context, R.string.nickname_required)));
		this.form.addField(Field.using(password).validate(
				MatchPattern.build(context, ".{5,10}", R.string.password_length)));
		this.form.addField(Field.using(password2).validate(
				MatchPattern.build(context, ".{5,10}", R.string.password_length)));

		this.btnSave.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				presenter.onSave();
			}
		});
		this.userEmail.setOnFocusChangeListener(new OnValueChangeEventListener() {

			@Override
			public void onValueChanged(View v, CharSequence curValue) {
				presenter.onUserEmailChanged();
			}

		});
		this.password.setOnFocusChangeListener(new OnValueChangeEventListener() {

			@Override
			public void onValueChanged(View v, CharSequence curValue) {
				presenter.onPasswordChanged();
			}
		});
		this.password2.setOnFocusChangeListener(new OnValueChangeEventListener() {

			@Override
			public void onValueChanged(View v, CharSequence curValue) {
				presenter.onPassword2Changed();
			}
		});
		
		this.btnBreakUp.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				presenter.onBreakUp();
			}
		});

		this.btnDropSingleMode.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				presenter.onDropSingleMode();
			}
		});

		this.btnDropTestMode.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				presenter.onDropTestMode();
			}
		});

	}

	public UserFormWidget(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public UserFormWidget(Context context) {
		this(context, null);
	}

	@Override
	public HasText caption() {
		return HasTextWrapper.from(caption, this);
	}

	@Override
	public HasValue<String> userEmail() {
		return HasValueWrapper.from(userEmail, this);
	}

	@Override
	public HasValue<String> nickName() {
		return HasValueWrapper.from(nickName, this);
	}

	@Override
	public HasValue<Gender> gender() {
		return HasValueWrapper.from(gender, this, ArrayUtils.insertElement(Gender.class, Gender.values(), null, 0));
	}

	@Override
	public HasValue<String> password() {
		return HasValueWrapper.from(password, this);
	}

	@Override
	public HasValue<String> password2() {
		return HasValueWrapper.from(password2, this);
	}

	@Override
	public void checkEmail() {
		this.presenter.onCheckEmail();
	}

	@Override
	public void editUser(User user) {
		this.presenter.onEditUser(user);
	}

	@Override
	public void setTryLoginOnSave(boolean tryLoginOnSave) {
		this.tryLoginOnSave = tryLoginOnSave;
	}

	@Override
	public boolean isTryLoginOnSave() {
		return tryLoginOnSave;
	}

	@Override
	public void nickNameFocus() {
		this.nickName.requestFocus();
	}

	@Override
	public HasEnabled userEmailEnabled() {
		return HasEnabledWrapper.from(userEmail, this);
	}

	@Override
	public HasText saveActionText() {
		return HasTextWrapper.from(btnSave, this);
	}

	@Override
	public HasEnabled saveEnabled() {
		return HasEnabledWrapper.from(btnSave, this);
	}

	@Override
	public HasLoader savingIndicator() {
		return HasLoaderWrapper.fromVisible(this.savingLoader);
	}

	@Override
	public Info extraInfo() {
		return this.extraInfo;
	}

	@Override
	public HasLoader tryingLoginIndicator() {
		return HasLoaderWrapper.fromVisible(lblTryingLogin, this);
	}

	@Override
	public HasVisibility couplePanel() {
		return HasVisibilityWrapper.from(couplePanel, this);
	}

	@Override
	public HasText coupleName() {
		return HasTextWrapper.from(coupleInfo);
	}

	@Override
	public void editUser(String userId) {
		this.presenter.onEditUser(userId);
	}

	@Override
	public boolean checkFormValidity() {
		return form.isValid();
	}

	@Override
	public HasLoader gettingUserIndicator() {
		return HasLoaderWrapper.fromVisible(this.gettingLoader);
	}

	@Override
	public Info userEmailCheckInfo() {
		return this.userEmailCheckInfo;
	}

	@Override
	public Info passwordCheckInfo() {
		return this.passwordCheckInfo;
	}

	@Override
	public HasLoader breakingUpIndicator() {
		return HasLoaderWrapper.fromVisible(this.breakingUpLoader);
	}

	@Override
	public void setPasswordChangeEnabled(boolean enabled) {
		passwordDiv.setVisibility(enabled ? View.VISIBLE : View.GONE);
	}

	@Override
	public boolean isPasswordChangeEnabled() {
		return passwordDiv.getVisibility() == View.VISIBLE;
	}

	@Override
	public HasVisibility downloadApp() {
		return HasVisibilityWrapper.from(btnDownloadApp, this);
	}

	@Override
	public HasVisibility singlePanel() {
		return HasVisibilityWrapper.from(singlePanel, this);
	}

	@Override
	public HasVisibility testPanel() {
		return HasVisibilityWrapper.from(testPanel, this);
	}

	@Override
	public HasLoader droppingSingleModeIndicator() {
		return HasLoaderWrapper.fromVisible(this.dropSingleModeLoader);
	}

	@Override
	public HasLoader droppingTestModeIndicator() {
		return HasLoaderWrapper.fromVisible(this.dropTestModeLoader);
	}

}
